﻿using System;
using System.Linq;
using System.Web;
using System.Web.UI;
using Cms.Application.WebFramework.Presenters;
using Cms.Application.WebFramework.Views;
using Cms.Domain;
using Cms.Domain.Authentication;
using Cms.Web.Framework.Infrastructure;
using iLib.Web.Mvc;
using iLib.Web.UI;

namespace Cms.Web.Framework.Controls
{
    public class Page : System.Web.UI.Page, IPageView
    {
        private RequestDetails _details;
        private PagePresenter _presenter;

        public Page()
        {
            _details = (RequestDetails)HttpContext.Current.Items["RequestDetails"];
            if (_details == null || _details.Page == null) // A direct request for page.aspx was made
                return;
            MasterPageFile = "~/__System/DetailTemplates/" + _details.DetailTemplate.ID + ".master";
        }

        public RequestDetails RequestDetails
        {
            get { return _details; }
            set { _details = value; }
        }
        
        public PagePresenter Presenter
        {
            get { return _presenter; }
        }

        #region IPageView Members

        int IPageView.UserID
        {
            get
            {
                try
                {
                    if (User.Identity.Name != string.Empty)
                    {
                        AuthenticatedUser user = Conversion.ToAuthenticatedUser(User.Identity.Name);
                        return user.UserID;
                    }
                }
                catch
                {
                }
                return -1;
            }
        }
        
        public int AdministratorID
        {
            get
            {
                try
                {
                    if (User.Identity.Name != string.Empty)
                    {
                        AuthenticatedUser user = Conversion.ToAuthenticatedUser(User.Identity.Name);
                        return user.AdministratorID;
                    }
                }
                catch
                {
                }
                return -1;
            }
        }
        
        public int PageID
        {
            get
            {
                if (_details.Page != null)
                    return _details.Page.ID;
                return -1;
            }
        }

        public void RedirectUserToLoginPage(string loginPageUrl)
        {
            Response.Redirect(loginPageUrl);
        }

        #endregion

        public override void VerifyRenderingInServerForm(Control control)
        {
            return;
        }
        
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (_details == null) // A direct request for page.aspx was made
                return;
            _presenter = new PagePresenter(this);
            _details.RenderContent();
        }
        
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            //Response.Cache.SetCacheability(HttpCacheability.Public);
            //Response.Cache.SetExpires(DateTime.Now.AddSeconds(10));
            //Response.Cache.SetValidUntilExpires(true);
            //Response.Cache.VaryByParams.IgnoreParams = true;

            Page.MaintainScrollPositionOnPostBack = true;
            Page.Header.Controls.AddAt(0, new LiteralControl("<base href=\"" + Url.FullPath + "\" />"));
            if (_details.Page == null || !_details.Page.LocalizedProperties.ContainsKey(_details.Locale.ID))
                return;
            Page.Title = _details.Page.LocalizedProperties[_details.Locale.ID].Title;
            var metaDescription = new LiteralControl
                                      {
                                          Text =
                                              @"<meta name=""description"" content=""" +
                                              _details.Page.LocalizedProperties[_details.Locale.ID].Description +
                                              @""" />"
                                      };
            Page.Header.Controls.Add(metaDescription);
            var metaKeywords = new LiteralControl
                                   {
                                       Text =
                                           @"<meta name=""keywords"" content=""" +
                                           _details.Page.LocalizedProperties[_details.Locale.ID].Keywords +
                                           @""" />"
                                   };
            Page.Header.Controls.Add(metaKeywords);
        }
        
        protected override void OnPreRenderComplete(EventArgs e)
        {
            base.OnPreRenderComplete(e);
            if (AdministratorID > 0)
            {
                _presenter.LogVisitedPublicUrl(_details.QueryString);
                RenderPublicAdminMenu();
            }
            foreach (
                Stylesheet stylesheet in
                    _details.MasterTemplate.GetStylesheets().Where(
                        stylesheet => stylesheet.Context == StylesheetContext.Always))
            {
                Header.Controls.Add(new LiteralControl("<link rel=\"stylesheet\" type=\"text/css\" href=\"" +
                                                       Url.VirtualPath + "__System/Stylesheets/" +
                                                       stylesheet.ID + ".css?v=" +
                                                       stylesheet.SourceCode.CurrentVersion.Timestamp + "\" />"));
            }
            foreach (
                Stylesheet stylesheet in
                    _details.MasterTemplate.GetStylesheets().Where(
                        stylesheet => stylesheet.Context == StylesheetContext.Print))
            {
                Header.Controls.Add(
                    new LiteralControl("<link rel=\"stylesheet\" type=\"text/css\" media=\"print\" href=\"" +
                                       Url.VirtualPath + "__System/Stylesheets/" +
                                       stylesheet.ID + ".css?v=" +
                                       stylesheet.SourceCode.CurrentVersion.Timestamp + "\" />"));
            }
            if (!string.IsNullOrEmpty(_details.Page.HeadHtml))
                Header.Controls.Add(new LiteralControl(_details.Page.HeadHtml));
            if (!string.IsNullOrEmpty(_details.Page.BodyTopHtml))
                Form.Controls.AddAt(0, new LiteralControl(_details.Page.BodyTopHtml));
            if (!string.IsNullOrEmpty(_details.Page.BodyBottomHtml))
                Form.Controls.Add(new LiteralControl(_details.Page.BodyBottomHtml));
        }

        protected void AddValidationError(long code, string message, string validationGroup, params string[] sources)
        {
            ValidationError validationError = new ValidationError(message, code, validationGroup, sources);
            bool alreadyAdded = false;
            if (code > 0)
            {
                alreadyAdded = this.Validators.Cast<IValidator>().Any(validator => validator is ValidationError && code == ((ValidationError) validator).Code);
            }
            if (!alreadyAdded)
            {
                this.Validators.Add(validationError);
            }
        }

        private void RenderPublicAdminMenu()
        {
            Form.Controls.Add(LoadControl("~/Admin/PublicAdminMenu.ascx"));
            Header.Controls.Add(
                new LiteralControl(
                    "<link rel=\"stylesheet\" type=\"text/css\" href=\"Admin/Css/PublicAdminMenu.css\" />"));
            foreach (
                Stylesheet stylesheet in
                    _details.MasterTemplate.GetStylesheets().Where(
                        stylesheet => stylesheet.Context == StylesheetContext.PublicAsAdmin))
            {
                Header.Controls.Add(new LiteralControl("<link rel=\"stylesheet\" type=\"text/css\" href=\"" +
                                                       Url.VirtualPath + "__System/Stylesheets/" +
                                                       stylesheet.ID + ".css?v=" +
                                                       stylesheet.SourceCode.CurrentVersion.Timestamp + "\" />"));
            }
        }
    }
}